<?php

    ##################################################
    #
    # Copyright (c) 2004-2008 OIC Group, Inc.
    #
    # This file is part of Exponent
    #
    # Exponent is free software; you can redistribute
    # it and/or modify it under the terms of the GNU
    # General Public License as published by the Free
    # Software Foundation; either version 2 of the
    # License, or (at your option) any later version.
    #
    # GPL: http://www.gnu.org/licenses/gpl.txt
    #
    ##################################################

    class section {
        /*
        * Common Form helper method
        *
        * This method, intended to be used solely by other methods of the
        * section class, creates a base form that all other page types can
        * build off of.  This form includes a name textbox, and either a rank
        * meta field (hidden input) or a rank dropdown.
        */
        function _commonForm(&$object) {
            $i18n = exponent_lang_loadFile('datatypes/section.php');

            // Create a new blank form.
            $form = new form();

            if (!isset($object->id)) {
                // This is a new section, so we need to set up some defaults.
                $object->name = '';
                $object->sef_name = '';
                $object->active = 1;
                $object->public = 1;
                $object->language = LANG;
                $object->new_window = 0;
                $object->subtheme = '';
                $object->id=null;
                // sept 15, 2010 - 2 - help user can change section type - trungdt - begin
                $object->alias_type = 0; //
                // sept 15, 2010 - 2 - help user can change section type - trungdt - end 

                $object->page_title = SITE_TITLE;
                $object->keywords = SITE_KEYWORDS;
                $object->description = SITE_DESCRIPTION;
                $object->css_class = "";

                if (!isset($object->parent)) {
                    // This is another precaution.  The parent attribute
                    // should ALWAYS be set by the caller.
                    //FJD - if that's the case, then we should die.
                    die(SITE_403_REAL_HTML);
                    //$object->parent = 0;
                }
                $form->meta('create_new', 1);
            } else {
                // If we are editing the section, we should store the section's id
                // in a hidden value, so that it comes through when the form is
                // submitted.
                $form->meta('id',  $object->id); // we build other way to store ID
                $form->meta('create_new', 0);
            }

            // The name of the section, as it will be linked in the section hierarchy.
            $form->register('name',$i18n['name'],new textcontrol($object->name));
            $form->register(null,'',new htmlcontrol('<p>If you don\'t put in an SEF Name one will be generated.  SEF names can only contain alpha-numeric characters, hyphens and underscores.</p>'));
            $form->register('sef_name',$i18n['sef_name'],new textcontrol($object->sef_name));

            if (!isset($object->id)) {
                // This is a new section, so we can add the positional dropdown
                // Pull the database object in from the global scope.
                global $db;
                // Retrieve all of the sections that are siblings of the new section
                $sections = $db->selectObjects('section','(language = "' . LANG .'") AND (parent='.$object->parent.')');

                if (count($sections) && $object->parent >= 0) {
                    // Initialize the sorting subsystem so that we can order the sections
                    // by rank, ascending, and get the proper ordering.
                    if (!defined('SYS_SORTING')) require_once(BASE.'subsystems/sorting.php');
                    usort($sections,'exponent_sorting_byRankAscending');

                    // Generate the Position dropdown array.
                    $positions = array($i18n['position_top']);
                    foreach ($sections as $section) {
                        $positions[] = sprintf($i18n['position_after'],$section->name);
                    }
                    $form->register('rank',$i18n['rank'],new dropdowncontrol(count($positions)-1,$positions));
                } else {
                    // If there are no siblings, the new section gets the first
                    // slot, with a rank of 0.
                    $form->meta('rank',0);
                }
                // Store the section's parent in a hidden field, so that it comes through
                // when the form is submitted.
                $form->meta('parent',$object->parent);
            } else if ($object->parent >= 0) {
                // Allow them to change parents, but not if the section is outside of the hiearchy (parent > 0)
                $form->register('parent',$i18n['parent'],new dropdowncontrol($object->parent,navigationmodule::levelDropdownControlArray(0,0,array($object->id),1)));
            }
            $form->register('language',$i18n['language'],new dropdowncontrol($object->language, exponent_lang_list()));

            if (!isset($object->id)) 
            {
                $form->register('id',"Link to Page",new navlinkcontrol($object->id)); 
            }
            $form->register('new_window',$i18n['new_window'],new checkboxcontrol($object->new_window,true));

            $css_class=array(
                ""=>"No icon",
                "home"=>"Home",
                "at"=>"At sign",
                "quote"=>"Quote sign",
                "quote-alt"=>"Quote alternative",
                "arrow-up"=>"Arrow up",
                "arrow-right"=>"Arrow right",
                "arrow-bottom"=>"Arrow bottom",
                "arrow-left"=>"Arrow left",
                "arrow-up-alt"=>"Arrow up alternative",
                "arrow-right-alt"=>"Arrow right alternative",
                "arrow-bottom-alt"=>"Arrow bottom alternative",
                "arrow-left-alt"=>"Arrow left alternative",
                "move"=>"Move",
                "move-vertical"=>"Move vertical",
                "move-horizontal"=>"Move Horizontal",
                "move-alt"=>"Move alternative",
                "move-vertical-alt"=>"Move vertical alternative",
                "move-horizontal-alt"=>"Move horizontal alternative",
                "cursor"=>"Cursor",
                "plus"=>"Plus",
                "plus-alt"=>"Plus alternative",
                "minus"=>"Minus",
                "minus-alt"=>"Minus alternative",
                "new-window"=>"New window",
                "dial"=>"Dial",
                "lightbulb"=>"Lightbulb",
                "link"=>"Link",
                "image"=>"Image",
                "Article"=>"Article",
                "read-more"=>"Read more",
                "headphones"=>"Headphones",
                "equalizer"=>"Equalizer",
                "fullscreen"=>"Fullscreen",
                "exit-fullscreen"=>"Exit Fullscreen",
                "spin"=>"Spin",
                "spin-alt"=>"Spin 2",
                "moon"=>"Moon",
                "map-pin"=>"Map pin",
                "pin"=>"Pin",
                "eyedropper"=>"Eyedropper",
                "denied"=>"Denied",
                "calendar"=>"Calendar",
                "calendar-alt"=>"Calendar 2",
                "bolt"=>"Bolt",
                "clock"=>"Clock",
                "document"=>"Document",
                "book"=>"Book",
                "book-alt"=>"Book 2",
                "book-alt"=>"Book 2",
                "magnifying-glass"=>"Magnifying-Glass",
                "tag"=>"Tag",
                "heart"=>"Heart",
                "info"=>"Info",
                "chat"=>"Chat",
                "chat-alt"=>"Chat 2",
                "key"=>"Key",
                "unlocked"=>"Unlocked",
                "locked"=>"locked",
                "mail"=>"Mail",
                "mail-alt"=>"Mail 2",
                "mail-alt"=>"Mail 2",
                "phone"=>"Phone",
                "box"=>"Box",
                "pencil"=>"Pencil",
                "pencil-alt"=>"Pencil 2",
                "comment"=>"Comment",
                "comment-alt"=>"Comment 2",
                "comment-alt"=>"Comment 2",
                "rss"=>"RSS",
                "star"=>"Star",
                "trash"=>"Trash",
                "user"=>"User",
                "volume"=>"Volume",
                "mute"=>"Mute",
                "cog"=>"Cog",
                "x"=>"X",
                "x-alt"=>"X 2",
                "check"=>"check",
                "check-alt"=>"Check alt",
                "beaker"=>"Beaker",
                "beaker-alt"=>"Beaker alt",
            );
            $form->register('css_class',"Menu icon",new dropdowncontrol($object->css_class, $css_class));
            
            // sept 15, 2010: trungdt add this line to support page alias type change - begin
            $aAliasType=array(0=>"Content page", 1=>"External website link",
                2=>"Internal website section link");
            $form->register('alias_type',"Section Alias type",new dropdowncontrol($object->alias_type, $aAliasType));
            // sept 15, 2010: trungdt add this line to support page alias type change - end

            // Return the form to the calling scope, which should always be a
            // member method of this class.
            return $form;
        }

        function moveStandaloneForm($object = null) {
            $i18n = exponent_lang_loadFile('datatypes/section.php');

            // Initialize the forms subsystem for use.
            if (!defined('SYS_FORMS')) require_once(BASE.'subsystems/forms.php');
            exponent_forms_initialize();

            $form = section::_commonForm($object);
            $form->unregister('name');

            global $db;
            $standalones = array();
            foreach ($db->selectObjects('section','parent = -1') as $s) {
                $standalones[$s->id] = $s->name;
            }

            if (!defined('SYS_SORTING')) include_once(BASE.'subsystems/sorting.php');
            $form->register('page',$i18n['standalone_page'],new dropdowncontrol(0,$standalones));
            $form->register('submit','',new buttongroupcontrol($i18n['save'],'',$i18n['cancel']));
            return $form;
        }

        /*
        * Content Page Form method
        *
        * This method returns a Form object to be used when allowing the user
        * to create a new normal Content Page or edit an existing one.
        *
        * @param Object $object The section object to build the form from.
        *
        * @return Form A form object that can be used to create a new section, or
        *    edit an existing one.
        */
        function form($object = null) {
            $i18n = exponent_lang_loadFile('datatypes/section.php');

            // Initialize the forms subsystem for use.
            if (!defined('SYS_FORMS')) require_once(BASE.'subsystems/forms.php');
            exponent_forms_initialize();

            // Grab the basic form that all page types share
            // This has the name and positional dropdowns registered.
            // This call also initializes the section object, if it is not an existing section.
            $form = section::_commonForm($object);

            // Register the sub themes dropdown.
            $form->register('subtheme',$i18n['subtheme'],new dropdowncontrol($object->subtheme,exponent_theme_getSubThemes()));
            
            if ($object->parent == -1)
            {
                global $db;
                
                $series_temp=$db->selectDropdown("section","section_cat"," language = '".LANG."' GROUP BY section_cat");
                
                $series=array();
                $series['no_selected']=$i18n['series_add_new'];
                $series['']=$i18n['section_category_default'];
                $series_default = "";
                foreach ($series_temp as $k=>$v)
                {
                    if (trim($v)!="")
                    {
                        $series[$v]=$v;      
                    }
                    if ($object->section_cat == $v)
                    $series_default= $v;
                }
                $form->register('series_dropdown',$i18n['series'],new dropdowncontrol($series_default,$series));
                $form->register(null,'',new htmlcontrol($i18n['selectseriesnotify']));
                $form->register('section_cat','',new textcontrol(""));
            }

            // Register the 'Active?' and 'Public?' checkboxes.
            $form->register('active',$i18n['active'],new checkboxcontrol($object->active));
            $form->register('public',$i18n['public'],new checkboxcontrol($object->public));

            // Register the Page Meta Data controls.
            $form->register('page_title',$i18n['page_title'],new textcontrol($object->page_title));
            $form->register('keywords',$i18n['keywords'],new texteditorcontrol($object->keywords,5,25,false));
            $form->register('description',$i18n['description'],new texteditorcontrol($object->description,5,25,false));
            
            // Add a Submit / Cancel button.
            $form->register('submit','',new buttongroupcontrol($i18n['save'],'',$i18n['cancel']));

            // Return the form to the calling scope (usually an action in the navigation module).
            return $form;
        }

        /*
        * External Alias Form method
        *
        * This method returns a form object to be used when allowing the user
        * to create a new section that is actually a link to a website outside of the
        * Exponent-managed site.
        *
        * @param Object $object The section object to build the form from.
        *
        * @return Form A form object that can be used to create a new section, or
        *    edit an existing one.
        */
        function externalAliasForm($object = null) {
            $i18n = exponent_lang_loadFile('datatypes/section.php');

            // Initialize the forms subsystem for use.
            if (!defined('SYS_FORMS')) require_once(BASE.'subsystems/forms.php');
            exponent_forms_initialize();

            // Grab the basic form that all page types share
            // This has the name and positional dropdowns registered.
            // This call also initializes the section object, if it is not an existing section.
            $form = section::_commonForm($object);

            // sept 15, 2010 - 3 - trungdt - make external website link can select file - begin
            if (!$object)
            {
                $object->file_id=-1;
                $object->external_link='';
            }
            $form->register(null,'',new htmlcontrol('<p>Select file uploaded in server or point to your URL<br>If you has selected an uploaded file, and now, you point to new URL, system will automaticaly using your URL instead of your file. </p>'));
            if (!isset($object->external_link)) $object->external_link = '';
            // Add a textbox the user can enter the external website's URL into.
            //$form->register('file_id','File', new ajax_select_file('file_id',0,$object->file_id,true));
            $form->register('external_link',$i18n['external_link'],new textcontrol($object->external_link));
            // sept 15, 2010 - 3 - trungdt - make external website link can select file - begin

            // Add the'Public?' checkbox.  The 'Active?' checkbox is omitted, because it makes no sense.
            $form->register('public',$i18n['public'],new checkboxcontrol($object->public));

            // Add a Submit / Cancel button.
            $form->register('submit','',new buttongroupcontrol($i18n['save'],'',$i18n['cancel']));

            // Return the form to the calling scope (usually an action in the navigation module).
            return $form;
        }

        /*
        * Internal Alias Form method
        *
        * This method returns a form object to be used when allowing the user
        * to create a new section that is actually a link to another page in the
        * Exponent site hierarchy.
        *
        * @param Object $object The section object to build the form from.
        *
        * @return Form A form object that can be used to create a new section, or
        *    edit an existing one.
        */
        function internalAliasForm($object = null) {
            $i18n = exponent_lang_loadFile('datatypes/section.php');

            // Initialize the forms subsystem for use.
            if (!defined('SYS_FORMS')) require_once(BASE.'subsystems/forms.php');
            exponent_forms_initialize();

            // Initialization
            if (!isset($object->id)) {
                $object->internal_id = 0;
            }

            // Grab the basic form that all page types share
            // This has the name and positional dropdowns registered.
            // This call also initializes the section object, if it is not an existing section.
            $form = section::_commonForm($object);

            // Add a dropdown to allow the user to choose an internal page.
            $form->register('internal_id',$i18n['internal_link'],new dropdowncontrol($object->internal_id,navigationmodule::levelDropDownControlArray(0,0)));

            // Add the'Public?' checkbox.  The 'Active?' checkbox is omitted, because it makes no sense.
            $form->register('public',$i18n['public'],new checkboxcontrol($object->public));

            // Add a Submit / Cancel button.
            $form->register('submit','',new buttongroupcontrol($i18n['save'],'',$i18n['cancel']));

            // Return the form to the calling scope (usually an action in the navigation module).
            return $form;
        }

        /*
        * Pageset Form method
        *
        * This method returns a form object to be used when allowing the user
        * to create a new section using a user-defined Pageset.
        *
        * @param Object $object The section object to build the form from.
        *
        * @return Form A form object that can be used to create a new section, or
        *    edit an existing one.
        */
        function pagesetForm($object = null) {
            $i18n = exponent_lang_loadFile('datatypes/section.php');

            // Initialize the forms subsystem for use.
            if (!defined('SYS_FORMS')) require_once(BASE.'subsystems/forms.php');
            exponent_forms_initialize();

            // Grab the basic form that all page types share
            // This has the name and positional dropdowns registered.
            // This call also initializes the section object, if it is not an existing section.
            $form = section::_commonForm($object);

            // Add a dropdown to allow the user to choose which pageset they want.
            // Pull the database object in from the global scope.
            global $db;
            // A holding array, which will become the source of the dropdown
            $pagesets = array();
            foreach ($db->selectObjects('section_template','parent=0') as $pageset) {
                // Grab each pageset and store its name and id.  The id will be used when updating.
                $pagesets[$pageset->id] = $pageset->name;
            }
            $form->register('pageset',$i18n['pageset'],new dropdowncontrol(0,$pagesets));

            // Add the'Public?' checkbox.  The 'Active?' checkbox is omitted, because it makes no sense.
            $form->register('public',$i18n['public'],new checkboxcontrol($object->public));

            // Add a Submit / Cancel button.
            $form->register('submit','',new buttongroupcontrol($i18n['save'],'',$i18n['cancel']));

            // Return the form to the calling scope (usually an action in the navigation module).
            return $form;
        }

        // Make section ID
        /*
        Make section ID method
        ABSoft - 7/25/2009 - Immanuel192
        Return ID for new section creation    
        */
        function _make_section_id($values, $object)
        {
            global $db;
            $lang_number = exponent_lang_get_number($object->language);
            if ($values['create_new'] == 0)
                $new_id=$values['id']; // save old ID - for edit section
            else
            {
                $input_id = trim($values['id']); // user input ID
                if ($input_id !="")
                {
                    // if user enter SEF name => translate it to section ID
                    $temp = $db->selectObject("section","(sef_name = '".$input_id."') OR (id = {$input_id})");
                    if ($temp) // if we have at least one item
                    {
                        $input_id = $temp->id;
                        // get language ID
                        $temp=exponent_lang_get_number($temp->language);
                        // remove language prefix
                        $input_id=substr($input_id,strlen($temp)); 
                    }
                    // okies, here we check New ID is a right value or not?
                    $new_id= $lang_number. $input_id;
                    $temp = $db->selectObject('section', "id = " . $new_id);
                    if ($temp) // error, this ID is wrong. 
                    {
                        validator::failAndReturnToForm('The ID specified in the PAGE ID field is a duplicate of an existing page.');
                    }
                    // okies, here, we have a good ID
                }
                else{
                    // if $input_id is null, so, System must generate new ID
                    $temp="select substr(id,2) as f1 from " . $db->prefix ."section where substr(id,1,1) ='".exponent_lang_get_number($object->language)."'";
                    $temp=$db->selectObjectsBySql($temp);
                    if (!$temp)
                        $temp =1; //assum that no pages in this language, set id =1
                    else
                    { 
                        $temp_index=array();
                        foreach ($temp as $key => $value)
                        {
                            $temp_index[$value->f1] = $value->f1;
                        } // here, we had build an ID array of created page, now, search for 
                        // ID which not in this array => the ID we need
                        $temp=1;
                        while (0<1) // belive that this loop is not endless
                        {
                            if (isset($temp_index[$temp]))  
                                $temp++;
                            else
                                break;
                        } // okies, after this loop, the $temp variable is the ID value that we need
                    }
                    // new ID
                    $new_id=$lang_number . $temp;
                } 
            }   
            return $new_id;
        }


        // Update methods

        /*
        * Update Object helper method
        *
        * This method is a complement to _commonForm, and updates the name
        * and rank of the passed object using the passed values.
        *
        * @param array $values The data received from the form submission
        * @param object $object The section object to update
        *
        * @return object The updated section object.
        */
        function _updateCommon($values,$object) {
            $object->name = $values['name'];
            // Sept 14, 2010: immanuel192 update this line, support automatic text to vietnamese translate
            // with no mark - begin
            if (trim($values['sef_name']) == "") // if sef_name is empty
            {
                $values['sef_name']=$values['name'];
            }
            $object->sef_name = _to_vietnamese_with_nomark($values['sef_name']);
            // Sept 14, 2010: immanuel192 update this line, support automatic text to vietnamese translate
            // with no mark - end
            // sept 15, 2010: trungdt - update section alias type - begin
            $object->alias_type = intval($values['alias_type']);
            if (!(($object->alias_type>=0) && ($object->alias_type<=2))) // in 0, 1, 2 only
            {
                $object->alias_type = 0 ; // default is content page which value is 0
            }
            // sept 15, 2010: trungdt - update section alias type - end
            $object->css_class = $values['css_class'];
            $object->language = $values['language'];
            $object->id= section::_make_section_id($values, $object);
            if (isset($values['rank'])) $object->rank = $values['rank'];
            if (isset($values['parent'])) $object->parent = $values['parent'];
            $object->new_window = (isset($values['new_window']) ? 1 : 0);
            return $object;
        }

        /*
        * Content Page Update method
        *
        * This method updates the passed section object's attributes using
        * the passed values.
        *
        * @param array $values The data received from the form submission
        * @param object $object The section object to update
        *
        * @return object The updated section object.
        */
        function update($values,$object) {
            $object = section::_updateCommon($values,$object);
            $object->subtheme = $values['subtheme'];
            $object->active = (isset($values['active']) ? 1 : 0);
            $object->public = (isset($values['public']) ? 1 : 0);
            $object->page_title = ($values['page_title'] != SITE_TITLE ? $values['page_title'] : "");
            $object->language = $values['language'];
            $object->keywords = ($values['keywords'] != SITE_KEYWORDS ? $values['keywords'] : "");
            $object->description = ($values['description'] != SITE_DESCRIPTION ? $values['description'] : "");
            
            // update section_cat
            if ($object->parent == -1){
            $object->section_cat=$values['section_cat'];
            if (!($values['series_dropdown']=='no_selected'))
            $object->section_cat=$values['series_dropdown'];
            }
            else
            {
                $object->section_cat = "";
            }
            return $object;
        }

        /*
        * External Alias Update method
        *
        * This method updates the passed section object's attributes using
        * the passed values.
        *
        * @param array $values The data received from the form submission
        * @param object $object The section object to update
        *
        * @return object The updated section object.
        */
        function updateExternalAlias($values,$object) {
            $object = section::_updateCommon($values,$object);

            $object->active = 1;
            $object->public = (isset($values['public']) ? 1 : 0);
            // sept 15, 2010: trungdt comment this line code, 
            // because alias_type has been updated in _commonUpdate
            // begin
            //$object->alias_type = 1;
            // sept 15, 2010: trungdt comment this line code, 
            // because alias_type has been updated in _commonUpdate
            // end
            $object->external_link = $values['external_link'];
            // sept 15, 2010 - ID3 - trungdt - make external alias section type can select file - begin
            // comment out this code, no need to add prefix http://
            /*if (!exponent_core_URLisValid($object->external_link)) {
            $object->external_link = 'http://' . $object->external_link;
            } */
            // sept 15, 2010 - 3 - trungdt - make external alias section type can select file - begin
            return $object;
        }

        /*
        * Internal Alias Update method
        *
        * This method updates the passed section object's attributes using
        * the passed values.
        *
        * @param array $values The data received from the form submission
        * @param object $object The section object to update
        *
        * @return object The updated section object.
        */
        function updateInternalAlias($values,$object) {
            $object = section::_updateCommon($values,$object);

            $object->active = 1;
            $object->public = (isset($values['public']) ? 1 : 0);
            // sept 15, 2010: trungdt comment this line code, 
            // because alias_type has been updated in _commonUpdate
            // begin
            //$object->alias_type = 2;
            // sept 15, 2010: trungdt comment this line code, 
            // because alias_type has been updated in _commonUpdate
            // end
            global $db;
            // We need to make sure we don't point to another link
            $section = $db->selectObject('section','id='.$values['internal_id']);
            while ($section->alias_type == 2) {
                // Find what it is pointing to.
                $section = $db->selectObject('section','id='.$section->internal_id);
            }
            // Pull the destination section's id into the internal_id field.  This works because
            // if the while loop didn't execute, we had a 'normal' page to begin with.  This check
            // doesn't guard against pointing an internal link to a section that is set up to
            // an external link -- that check will need to be done in the navigation module itself.
            $object->internal_id = $section->id;
            // Set the active state of the new section from the linked section.  The caller is
            // expected to catch this if a link to an inactive section is made, and that behaviour
            // is undesired.
            $object->active = $section->active;
            return $object;
        }

        /*
        * Pageset Update method
        *
        * This method updates the passed section object's attributes using
        * the passed values.
        *
        * @param array $values The data received from the form submission
        * @param object $object The section object to update
        *
        * @return object The updated section object.
        */
        function updatePageset($values,$object) {
            $object = section::_updateCommon($values,$object);

            $object->active = 1;
            $object->public = (isset($values['public']) ? 1 : 0);

            // Can't really do much with pageset updating, because we
            // need to save the section before we can add subsections or copy
            // any content.
            return $object;
        }

        // The following are helper functions for dealing with the Section datatype.

        /*
        * Determine Section Depth
        *
        * This method looks at a section ID, and figures out how deep in the
        * site hierarchy it is, and returns that number.  A top-level section has a
        * depth of 0, it's children all have a depth of 1, and so on.
        *
        * @param integer $id The id of the section to find the depth count for.
        *
        * @return integer The depth of the section.
        */
        function depth($id) {
            // To calculate a section's depth, we query its parents
            // until we find a parent with no parent (a top-level section).
            // The number of parents is the depth of the section.  For
            // instance, a top-level section has no parents and a depth
            // of 0.

            // Pull in the database object form the global scope.
            global $db;

            // Start out at depth 0.  The while loop will not execute if
            // the passed $id was that of a top-level section, so $depth
            // will still be set properly.
            $depth = 0;
            // Grab the section we were passed.
            $s = $db->selectObject("section","id=$id");
            while ($s->parent != 0) {
                // Section still has a parent.  Increment the depth counter.
                $depth++;
                // Get the section's parent's parent (grandparent)
                $s = $db->selectObject("section","id=".$s->parent);
            }
            return $depth;
        }

        function changeParent($section,$old_parent,$new_parent) {
            global $db;
            // Store new parent.
            $section->parent = $new_parent;

            $db->decrement('section','rank',1,'parent='.$old_parent . ' AND rank > ' . $section->rank);
            // Need to place this item at the end of the list of children for the new parent.
            $section->rank = $db->max('section','rank','parent','parent='.$new_parent);
            if ($section->rank === null) {
                $section->rank = 0;
            } else {
                $section->rank++;
            }

            return $section;
        }

        public static function isValidName($name=null) {
            if (empty($name)) return false;

            $match = array();
            $pattern = "/([^0-9a-z-_\+])/i";
            if (preg_match($pattern, $name, $match, PREG_OFFSET_CAPTURE)) {
                return false;
            } else {
                return true;
            }
        }

        public static function isDuplicateName($section=null) {
            if (empty($section)) return false;
            global $db;
            if (is_object($section)) {
                if (!empty($section->id)) {
                    $res = $db->selectValue('section', 'id', 'id != '.$section->id.' AND sef_name="'.$section->sef_name.'"');
                } else {
                    $res = $db->selectValue('section', 'id', 'sef_name="'.$section->sef_name.'"');
                }
            } elseif(is_string($section)) {
                $res = $db->selectValue('section', 'id', 'sef_name="'.$section.'"');
            }

            return empty($res) ? false : true;
        }
    }

?>
